组合逻辑环(Combinatorial loop)
简介
SpinalHDL将检查设计中是否存在组合逻辑环。
示例
下面的代码:
class TopLevel extends Component {
  val a = UInt(8 bits) // PlayDev.scala line 831
  val b = UInt(8 bits) // PlayDev.scala line 832
  val c = UInt(8 bits)
  val d = UInt(8 bits)
  a := b
  b := c | d
  d := a
  c := 0
}
会出现:
COMBINATORIAL LOOP :
  Partial chain :
    >>> (toplevel/a :  UInt[8 bits]) at ***(PlayDev.scala:831) >>>
    >>> (toplevel/d :  UInt[8 bits]) at ***(PlayDev.scala:834) >>>
    >>> (toplevel/b :  UInt[8 bits]) at ***(PlayDev.scala:832) >>>
    >>> (toplevel/a :  UInt[8 bits]) at ***(PlayDev.scala:831) >>>
  Full chain :
    (toplevel/a :  UInt[8 bits])
    (toplevel/d :  UInt[8 bits])
    (UInt | UInt)[8 bits]
    (toplevel/b :  UInt[8 bits])
    (toplevel/a :  UInt[8 bits])
一个可能的修复方式是:
class TopLevel extends Component {
  val a = UInt(8 bits) // PlayDev.scala line 831
  val b = UInt(8 bits) // PlayDev.scala line 832
  val c = UInt(8 bits)
  val d = UInt(8 bits)
  a := b
  b := c | d
  d := 42
  c := 0
}
误报
SpinalHDL检测组合逻辑环的算法可能是悲观的,并且可能会给出误报。如果出现误报,您可以手动禁用对某一信号的逻辑环的检查,如下所示:
class TopLevel extends Component {
  val a = UInt(8 bits)
  a := 0
  a(1) := a(0) // False positive because of this line
}
可以通过以下方式修复:
class TopLevel extends Component {
  val a = UInt(8 bits).noCombLoopCheck
  a := 0
  a(1) := a(0)
}
还应该指出,诸如 (a(1) := a(0)) 之类的赋值可能会使一些工具如 Verilator 无法适配。在这种情况下,使用 Vec(Bool(), 8) 可能更好。